"""
视频合并模块
用于将多个视频文件合并为一个完整的视频文件
"""

import os
import logging
import tempfile
import subprocess
from typing import List, Dict, Optional, Callable
from pathlib import Path
from dataclasses import dataclass
from enum import Enum
import hashlib
import json

try:
    import moviepy.editor as mp
    MOVIEPY_AVAILABLE = True
except ImportError:
    MOVIEPY_AVAILABLE = False
    logging.warning("MoviePy未安装，将使用FFmpeg进行视频合并")

from .file_scanner import VideoFileInfo


class MergeMethod(Enum):
    """合并方法枚举"""
    FFMPEG_CONCAT = "ffmpeg_concat"  # FFmpeg concat demuxer（推荐，最快）
    FFMPEG_FILTER = "ffmpeg_filter"  # FFmpeg filter complex
    MOVIEPY = "moviepy"  # MoviePy合并
    AUTO = "auto"  # 自动选择最佳方法


class VideoQuality(Enum):
    """视频质量枚举"""
    ORIGINAL = "original"  # 保持原始质量
    HIGH = "high"  # 高质量（CRF 18）
    MEDIUM = "medium"  # 中等质量（CRF 23）
    LOW = "low"  # 低质量（CRF 28）
    CUSTOM = "custom"  # 自定义参数


@dataclass
class MergeProgress:
    """合并进度信息"""
    current_file: str
    current_index: int
    total_files: int
    progress_percent: float
    elapsed_time: float
    estimated_remaining: float
    current_operation: str
    status: str  # 'preparing', 'processing', 'completed', 'error'


@dataclass
class MergeConfig:
    """合并配置"""
    method: MergeMethod = MergeMethod.AUTO
    quality: VideoQuality = VideoQuality.ORIGINAL
    output_format: str = "mp4"
    target_resolution: Optional[tuple] = None  # (width, height)
    target_fps: Optional[float] = None
    add_transitions: bool = False
    transition_duration: float = 0.5  # 转场时长（秒）
    audio_normalization: bool = True
    custom_ffmpeg_params: Optional[List[str]] = None
    temp_dir: Optional[str] = None
    # 背景音乐配置
    background_music_path: Optional[str] = None
    background_music_volume: float = 0.3  # 背景音乐音量 (0.0-1.0)
    background_music_fade: str = "in"  # 淡入淡出: "none", "in", "out", "both"
    background_music_start_time: float = 0.0  # 背景音乐起始时间（秒）


class VideoMerger:
    """视频合并器"""
    
    def __init__(self, config: MergeConfig = None):
        """
        初始化视频合并器
        
        Args:
            config: 合并配置
        """
        self.config = config or MergeConfig()
        self.logger = logging.getLogger(__name__)
        self.progress_callback: Optional[Callable[[MergeProgress], None]] = None
        self._current_progress = MergeProgress(
            current_file="", current_index=0, total_files=0,
            progress_percent=0, elapsed_time=0, estimated_remaining=0,
            current_operation="", status="preparing"
        )
    
    def set_progress_callback(self, callback: Callable[[MergeProgress], None]):
        """设置进度回调函数"""
        self.progress_callback = callback
    
    def merge_videos(self, video_files: List[VideoFileInfo], output_path: str) -> Dict:
        """
        合并视频文件
        
        Args:
            video_files: 视频文件列表（已排序）
            output_path: 输出文件路径
            
        Returns:
            合并结果
        """
        if not video_files:
            return {"success": False, "error": "没有提供视频文件"}
        
        if len(video_files) == 1:
            # 只有一个文件，直接复制
            return self._copy_single_file(video_files[0], output_path)
        
        # 验证文件
        valid_files = [f for f in video_files if f.is_valid and os.path.exists(f.path)]
        if not valid_files:
            return {"success": False, "error": "没有有效的视频文件"}
        
        if len(valid_files) != len(video_files):
            self.logger.warning(f"忽略了 {len(video_files) - len(valid_files)} 个无效文件")
        
        self.logger.info(f"开始合并 {len(valid_files)} 个视频文件")
        
        # 更新进度
        self._current_progress.total_files = len(valid_files)
        self._current_progress.status = "preparing"
        self._update_progress("准备合并视频文件")
        
        try:
            # 选择合并方法
            method = self._choose_merge_method(valid_files)
            self.logger.info(f"使用合并方法: {method.value}")
            
            # 执行合并
            if method == MergeMethod.FFMPEG_CONCAT:
                result = self._merge_with_ffmpeg_concat(valid_files, output_path)
            elif method == MergeMethod.FFMPEG_FILTER:
                result = self._merge_with_ffmpeg_filter(valid_files, output_path)
            elif method == MergeMethod.MOVIEPY:
                result = self._merge_with_moviepy(valid_files, output_path)
            else:
                return {"success": False, "error": f"不支持的合并方法: {method}"}
            
            if result["success"]:
                # 验证输出文件
                if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                    self._current_progress.status = "completed"
                    self._update_progress("视频合并完成")
                    
                    # 获取输出文件信息
                    output_info = self._get_output_info(output_path)
                    result.update(output_info)
                else:
                    result = {"success": False, "error": "输出文件无效或为空"}
            
            return result
        
        except Exception as e:
            self.logger.error(f"视频合并失败: {e}")
            self._current_progress.status = "error"
            self._update_progress(f"合并失败: {str(e)}")
            return {"success": False, "error": str(e)}
    
    def _choose_merge_method(self, video_files: List[VideoFileInfo]) -> MergeMethod:
        """选择最佳合并方法"""
        if self.config.method != MergeMethod.AUTO:
            return self.config.method
        
        # 检查FFmpeg是否可用
        if self._is_ffmpeg_available():
            # 检查视频格式是否一致
            formats = set(f.format for f in video_files)
            # 确保resolution是tuple而非list，以便可以进行哈希运算
            resolutions = set(tuple(f.resolution) if isinstance(f.resolution, list) else f.resolution 
                            for f in video_files if f.resolution[0] > 0)
            
            if len(formats) == 1 and len(resolutions) <= 1:
                # 格式和分辨率一致，使用最快的concat方法
                return MergeMethod.FFMPEG_CONCAT
            else:
                # 需要格式转换，使用filter方法
                return MergeMethod.FFMPEG_FILTER
        elif MOVIEPY_AVAILABLE:
            return MergeMethod.MOVIEPY
        else:
            raise Exception("没有可用的视频合并工具（FFmpeg或MoviePy）")
    
    def _merge_with_ffmpeg_concat(self, video_files: List[VideoFileInfo], output_path: str) -> Dict:
        """使用FFmpeg concat demuxer合并视频"""
        self._update_progress("使用FFmpeg concat方法合并")
        
        # 创建临时concat文件
        temp_dir = self.config.temp_dir or tempfile.gettempdir()
        # 生成唯一文件名，基于文件路径而不是整个对象
        file_paths_str = "|".join(f.path for f in video_files)
        concat_file = os.path.join(temp_dir, f"concat_{hashlib.md5(file_paths_str.encode()).hexdigest()[:8]}.txt")
        
        try:
            # 写入concat文件
            with open(concat_file, 'w', encoding='utf-8') as f:
                for video_file in video_files:
                    # 转义文件路径
                    escaped_path = video_file.path.replace("'", "'\"'\"'")
                    f.write(f"file '{escaped_path}'\n")
            
            # 构建FFmpeg命令
            cmd = [
                'ffmpeg', '-y',  # 覆盖输出文件
                '-f', 'concat',
                '-safe', '0',
                '-i', concat_file
            ]
            
            # 添加背景音乐处理
            if self.config.background_music_path and os.path.exists(self.config.background_music_path):
                # 如果有背景音乐，需要使用filter_complex而不是concat demuxer
                return self._merge_with_ffmpeg_filter(video_files, output_path)
            
            # 添加质量参数
            cmd.extend(self._get_quality_params())
            
            # 添加输出路径
            cmd.append(output_path)
            
            # 执行命令
            result = self._run_ffmpeg_command(cmd, video_files)
            
            return result
        
        finally:
            # 清理临时文件
            if os.path.exists(concat_file):
                os.remove(concat_file)
    
    def _merge_with_ffmpeg_filter(self, video_files: List[VideoFileInfo], output_path: str) -> Dict:
        """使用FFmpeg filter complex合并视频"""
        self._update_progress("使用FFmpeg filter方法合并")
        
        # 构建复杂过滤器 - 先缩放到统一分辨率再concat
        inputs = []
        filter_parts = []
        
        # 找到最大的分辨率作为目标分辨率
        max_width = max(f.resolution[0] for f in video_files if f.resolution[0] > 0)
        max_height = max(f.resolution[1] for f in video_files if f.resolution[1] > 0)
        
        for i, video_file in enumerate(video_files):
            inputs.extend(['-i', video_file.path])
            
            # 构建视频滤镜链：缩放 + 速率调整
            video_filter = f"[{i}:v]scale={max_width}:{max_height}:force_original_aspect_ratio=decrease:eval=frame,pad={max_width}:{max_height}:(ow-iw)/2:(oh-ih)/2,setsar=1"
            
            # 添加速率调整（如果不是1.0）
            if hasattr(video_file, 'speed') and video_file.speed != 1.0:
                # 使用setpts调整视频播放速率
                video_filter += f",setpts=PTS/{video_file.speed}"
            
            video_filter += f"[v{i}]"
            filter_parts.append(video_filter)
        
        # 处理音频速率调整
        audio_filter_parts = []
        for i, video_file in enumerate(video_files):
            if hasattr(video_file, 'speed') and video_file.speed != 1.0:
                # 使用atempo调整音频播放速率
                # atempo范围限制在0.5-100.0，对于超出范围的值需要链式处理
                speed = video_file.speed
                audio_filter = f"[{i}:a]"
                
                # 处理速率调整（链式atempo以支持更大范围）
                while speed > 2.0:
                    audio_filter += "atempo=2.0,"
                    speed /= 2.0
                while speed < 0.5:
                    audio_filter += "atempo=0.5,"
                    speed /= 0.5
                if speed != 1.0:
                    audio_filter += f"atempo={speed},"
                
                audio_filter = audio_filter.rstrip(',') + f"[a{i}]"
                audio_filter_parts.append(audio_filter)
            else:
                # 不需要速率调整的音频直接标记
                audio_filter_parts.append(f"[{i}:a]anull[a{i}]")
        
        # 连接所有视频和音频
        video_inputs = "".join(f"[v{i}]" for i in range(len(video_files)))
        audio_inputs = "".join(f"[a{i}]" for i in range(len(video_files)))
        
        # 基础的视频和音频连接
        all_filters = filter_parts + audio_filter_parts
        base_filter = ";".join(all_filters) + f";{video_inputs}concat=n={len(video_files)}:v=1:a=0[outv];{audio_inputs}concat=n={len(video_files)}:v=0:a=1[original_audio]"
        
        # 计算合并后的总时长（考虑速率调整）
        total_duration = sum(
            f.duration / (f.speed if hasattr(f, 'speed') and f.speed > 0 else 1.0) 
            for f in video_files if f.is_valid
        )
        
        # 处理背景音乐
        bg_music_index = None
        processed_music_path = None
        
        if self.config.background_music_path and os.path.exists(self.config.background_music_path):
            self.logger.info(f"开始预处理背景音乐:")
            self.logger.info(f"  - 音乐文件: {self.config.background_music_path}")
            self.logger.info(f"  - 音量设置: {self.config.background_music_volume:.1%}")
            self.logger.info(f"  - 淡入淡出: {self.config.background_music_fade}")
            self.logger.info(f"  - 起始时间: {self.config.background_music_start_time}秒")
            self.logger.info(f"  - 目标时长: {total_duration}秒")
            
            # 预处理背景音乐，生成临时文件
            processed_music_path = self._preprocess_background_music(
                self.config.background_music_path,
                total_duration,
                self.config.background_music_start_time,
                self.config.background_music_volume,
                self.config.background_music_fade
            )
            
            if processed_music_path:
                # 添加预处理后的背景音乐输入
                inputs.extend(['-i', processed_music_path])
                bg_music_index = len(video_files)  # 背景音乐的输入索引
                self.logger.info(f"使用预处理后的背景音乐: {processed_music_path}")
            else:
                self.logger.error("背景音乐预处理失败，跳过背景音乐")
        
        # 构建最终的filter complex
        if bg_music_index is not None:
            # 简单的混音，因为背景音乐已经预处理好了
            filter_complex = base_filter + f";[original_audio][{bg_music_index}:a]amix=inputs=2:duration=longest:dropout_transition=0[outa]"
            self.logger.info("使用预处理后的背景音乐进行简单混音")
        else:
            # 没有背景音乐，直接使用原始音频
            filter_complex = base_filter + ";[original_audio]anull[outa]"
        
        # 构建FFmpeg命令
        cmd = ['ffmpeg', '-y'] + inputs + [
            '-filter_complex', filter_complex,
            '-map', '[outv]',
            '-map', '[outa]'
        ]
        
        # 添加质量参数 - filter complex不能使用stream copy
        if self.config.quality == VideoQuality.ORIGINAL:
            # 使用高质量重新编码而不是stream copy
            cmd.extend(['-c:v', 'libx264', '-crf', '18', '-c:a', 'aac'])
        else:
            cmd.extend(self._get_quality_params())
        
        # 添加输出路径
        cmd.append(output_path)
        
        try:
            # 执行命令
            result = self._run_ffmpeg_command(cmd, video_files)
            
            # 清理预处理的临时音乐文件
            if processed_music_path and os.path.exists(processed_music_path):
                try:
                    os.remove(processed_music_path)
                    self.logger.info(f"已清理临时音乐文件: {processed_music_path}")
                except Exception as e:
                    self.logger.warning(f"清理临时音乐文件失败: {e}")
            
            return result
        except Exception as e:
            # 出错时也要清理临时文件
            if processed_music_path and os.path.exists(processed_music_path):
                try:
                    os.remove(processed_music_path)
                except:
                    pass
            raise e
    
    def _merge_with_moviepy(self, video_files: List[VideoFileInfo], output_path: str) -> Dict:
        """使用MoviePy合并视频"""
        if not MOVIEPY_AVAILABLE:
            return {"success": False, "error": "MoviePy未安装"}
        
        self._update_progress("使用MoviePy合并")
        
        try:
            clips = []
            
            for i, video_file in enumerate(video_files):
                self._current_progress.current_index = i
                self._current_progress.current_file = video_file.filename
                self._update_progress(f"加载视频片段: {video_file.filename}")
                
                clip = mp.VideoFileClip(video_file.path)
                clips.append(clip)
            
            self._update_progress("合并视频片段")
            
            # 合并视频
            final_clip = mp.concatenate_videoclips(clips)
            
            # 写入文件
            self._update_progress("写入输出文件")
            final_clip.write_videofile(
                output_path,
                verbose=False,
                logger=None,
                temp_audiofile_path=self.config.temp_dir
            )
            
            # 清理资源
            for clip in clips:
                clip.close()
            final_clip.close()
            
            return {"success": True, "method": "moviepy"}
        
        except Exception as e:
            self.logger.error(f"MoviePy合并失败: {e}")
            return {"success": False, "error": str(e)}
    
    def _copy_single_file(self, video_file: VideoFileInfo, output_path: str) -> Dict:
        """复制单个文件"""
        self._update_progress(f"复制单个文件: {video_file.filename}")
        
        try:
            import shutil
            shutil.copy2(video_file.path, output_path)
            
            return {
                "success": True,
                "method": "copy",
                "input_files": 1,
                "output_path": output_path
            }
        
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    def _run_ffmpeg_command(self, cmd: List[str], video_files: List[VideoFileInfo]) -> Dict:
        """运行FFmpeg命令"""
        try:
            self.logger.info(f"执行FFmpeg命令: {' '.join(cmd)}")
            
            process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            
            # 监控进度（简化版）
            stderr_output = []
            while True:
                line = process.stderr.readline()
                if not line:
                    break
                
                stderr_output.append(line)
                
                # 解析进度信息
                if "time=" in line:
                    self._parse_ffmpeg_progress(line)
            
            process.wait()
            
            if process.returncode == 0:
                return {
                    "success": True,
                    "method": "ffmpeg",
                    "input_files": len(video_files)
                }
            else:
                error_msg = "".join(stderr_output)
                self.logger.error(f"FFmpeg执行失败: {error_msg}")
                return {"success": False, "error": error_msg}
        
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    def _parse_ffmpeg_progress(self, line: str):
        """解析FFmpeg进度信息"""
        try:
            if "time=" in line:
                # 简化的进度解析
                import re
                time_match = re.search(r"time=(\d+):(\d+):(\d+.\d+)", line)
                if time_match:
                    hours = int(time_match.group(1))
                    minutes = int(time_match.group(2))
                    seconds = float(time_match.group(3))
                    current_time = hours * 3600 + minutes * 60 + seconds
                    
                    # 估算总时长（简化） - 这里需要传入实际的视频文件列表
                    # 暂时跳过进度估算，避免错误
                    total_duration = 0
                    if total_duration > 0:
                        progress = min(current_time / total_duration * 100, 100)
                        self._current_progress.progress_percent = progress
                        self._update_progress(f"处理中... {progress:.1f}%")
        except:
            pass
    
    def _get_quality_params(self) -> List[str]:
        """获取质量参数"""
        if self.config.quality == VideoQuality.ORIGINAL:
            return ['-c', 'copy']  # 复制流，不重新编码
        elif self.config.quality == VideoQuality.HIGH:
            return ['-c:v', 'libx264', '-crf', '18', '-c:a', 'aac']
        elif self.config.quality == VideoQuality.MEDIUM:
            return ['-c:v', 'libx264', '-crf', '23', '-c:a', 'aac']
        elif self.config.quality == VideoQuality.LOW:
            return ['-c:v', 'libx264', '-crf', '28', '-c:a', 'aac']
        elif self.config.quality == VideoQuality.CUSTOM and self.config.custom_ffmpeg_params:
            return self.config.custom_ffmpeg_params
        else:
            return ['-c:v', 'libx264', '-crf', '23', '-c:a', 'aac']
    
    def _is_ffmpeg_available(self) -> bool:
        """检查FFmpeg是否可用"""
        try:
            subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
            return True
        except (subprocess.CalledProcessError, FileNotFoundError):
            return False
    
    def _get_output_info(self, output_path: str) -> Dict:
        """获取输出文件信息"""
        try:
            stat = os.stat(output_path)
            
            info = {
                "output_path": output_path,
                "file_size": stat.st_size,
                "file_size_mb": stat.st_size / 1024 / 1024
            }
            
            # 尝试获取视频信息
            if MOVIEPY_AVAILABLE:
                try:
                    with mp.VideoFileClip(output_path) as clip:
                        info.update({
                            "duration": clip.duration,
                            "resolution": clip.size,
                            "fps": clip.fps
                        })
                except:
                    pass
            
            return info
        
        except Exception as e:
            self.logger.warning(f"无法获取输出文件信息: {e}")
            return {"output_path": output_path}
    
    def _update_progress(self, operation: str):
        """更新进度"""
        self._current_progress.current_operation = operation
        
        if self.progress_callback:
            self.progress_callback(self._current_progress)
        
        self.logger.info(f"进度: {operation}")
    
    def _preprocess_background_music(self, music_path: str, video_duration: float, 
                                   start_time: float, volume: float, fade: str) -> Optional[str]:
        """
        预处理背景音乐文件，生成临时音频文件
        
        Args:
            music_path: 原始音乐文件路径
            video_duration: 视频总时长（秒）
            start_time: 音乐起始时间（秒）
            volume: 音量（0.0-1.0）
            fade: 淡入淡出设置（"none", "in", "out", "both"）
            
        Returns:
            预处理后的临时音频文件路径，失败时返回None
        """
        try:
            # 创建临时文件路径
            temp_dir = self.config.temp_dir or tempfile.gettempdir()
            temp_filename = f"bg_music_{hashlib.md5(f'{music_path}_{start_time}_{volume}_{fade}'.encode()).hexdigest()[:8]}.wav"
            temp_music_path = os.path.join(temp_dir, temp_filename)
            
            self.logger.info(f"预处理背景音乐到临时文件: {temp_music_path}")
            
            # 先获取原始音频的时长
            probe_cmd = [
                'ffprobe', '-v', 'quiet', '-print_format', 'json', 
                '-show_format', '-show_streams', music_path
            ]
            
            try:
                probe_process = subprocess.Popen(probe_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
                probe_stdout, probe_stderr = probe_process.communicate()
                
                if probe_process.returncode == 0:
                    import json
                    probe_data = json.loads(probe_stdout)
                    original_duration = float(probe_data['format']['duration'])
                    self.logger.info(f"  - 原始音乐时长: {original_duration:.2f} 秒")
                else:
                    original_duration = 300  # 默认5分钟
                    self.logger.warning(f"无法获取音频时长，使用默认值: {original_duration} 秒")
            except Exception as e:
                original_duration = 300  # 默认5分钟
                self.logger.warning(f"获取音频时长失败: {e}，使用默认值: {original_duration} 秒")
            
            # 构建FFmpeg命令来预处理音乐
            cmd = [
                'ffmpeg', '-y',
                '-i', music_path
            ]
            
            # 构建音频滤镜链
            audio_filters = []
            
            # 1. 从指定时间开始截取
            if start_time > 0:
                audio_filters.append(f"atrim=start={start_time}")
                self.logger.info(f"  - 从 {start_time} 秒开始截取")
                effective_original_duration = max(0, original_duration - start_time)
            else:
                effective_original_duration = original_duration
            
            # 2. 循环播放以匹配视频时长
            # 精确匹配视频长度，只添加小缓冲防止浮点误差
            effective_duration = video_duration + 0.5  # 只添加0.5秒小缓冲防止浮点误差
            
            # 计算需要的循环次数
            if effective_original_duration > 0:
                # 计算精确需要的循环次数
                exact_loops_needed = effective_duration / effective_original_duration
                loop_count = max(1, int(exact_loops_needed) + 1)  # 只多加1次确保够用
            else:
                loop_count = 3  # 保险值，减少不必要的循环
            
            self.logger.info(f"  - 目标时长: {video_duration} 秒（精确缓冲: {effective_duration} 秒）")
            self.logger.info(f"  - 有效原始时长: {effective_original_duration:.2f} 秒")
            self.logger.info(f"  - 需要循环数: {exact_loops_needed:.2f}，实际循环次数: {loop_count} 次")
            
            # 使用计算出的循环次数
            audio_filters.append(f"aloop=loop={loop_count}")
            # 精确截取到视频长度，确保背景音乐和视频同时结束
            audio_filters.append(f"atrim=end={video_duration}")  # 精确匹配视频时长
            
            # 3. 调整音量
            if volume != 1.0:
                audio_filters.append(f"volume={volume}")
                self.logger.info(f"  - 音量调整: {volume:.1%}")
            
            # 4. 添加淡入淡出效果
            if fade in ["in", "both"]:
                audio_filters.append("afade=t=in:d=3")  # 3秒淡入
                self.logger.info("  - 添加3秒淡入效果")
            
            if fade in ["out", "both"]:
                audio_filters.append(f"afade=t=out:d=3:st={effective_duration-3}")  # 3秒淡出
                self.logger.info("  - 添加3秒淡出效果")
            
            # 构建完整的filter命令
            if audio_filters:
                filter_str = ",".join(audio_filters)
                cmd.extend(['-af', filter_str])
                self.logger.info(f"  - 音频滤镜: {filter_str}")
            
            # 输出参数
            cmd.extend([
                '-c:a', 'pcm_s16le',  # 使用PCM编码确保兼容性
                '-ar', '44100',       # 采样率
                '-ac', '2',           # 双声道
                temp_music_path
            ])
            
            self.logger.info(f"执行背景音乐预处理命令: {' '.join(cmd)}")
            
            # 执行预处理命令
            process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                universal_newlines=True
            )
            
            stdout, stderr = process.communicate()
            
            if process.returncode == 0:
                self.logger.info("背景音乐预处理成功")
                self.logger.info(f"预处理后的文件: {temp_music_path}")
                
                # 验证输出文件
                if os.path.exists(temp_music_path) and os.path.getsize(temp_music_path) > 0:
                    file_size = os.path.getsize(temp_music_path) / 1024 / 1024  # MB
                    self.logger.info(f"预处理后的文件大小: {file_size:.2f} MB")
                    return temp_music_path
                else:
                    self.logger.error("预处理后的文件无效或为空")
                    return None
            else:
                self.logger.error(f"背景音乐预处理失败: {stderr}")
                return None
        
        except Exception as e:
            self.logger.error(f"预处理背景音乐时出错: {e}")
            return None


# 便捷函数
def merge_videos_simple(video_files: List[VideoFileInfo], output_path: str, 
                       quality: VideoQuality = VideoQuality.ORIGINAL) -> Dict:
    """
    便捷函数：简单合并视频
    
    Args:
        video_files: 视频文件列表
        output_path: 输出路径
        quality: 视频质量
        
    Returns:
        合并结果
    """
    config = MergeConfig(quality=quality)
    merger = VideoMerger(config)
    return merger.merge_videos(video_files, output_path)


def merge_videos_with_progress(video_files: List[VideoFileInfo], output_path: str,
                              progress_callback: Callable[[MergeProgress], None],
                              config: MergeConfig = None) -> Dict:
    """
    便捷函数：带进度回调的视频合并
    
    Args:
        video_files: 视频文件列表
        output_path: 输出路径
        progress_callback: 进度回调函数
        config: 合并配置
        
    Returns:
        合并结果
    """
    merger = VideoMerger(config or MergeConfig())
    merger.set_progress_callback(progress_callback)
    return merger.merge_videos(video_files, output_path)